perm filename COMSCH.MSG[SCH,LSP]1 blob
sn#781412 filedate 1984-12-28 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00001 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 ENDMK
C⊗;
∂29-Nov-84 1009 RPG Comments on the Preliminary Report (2 pages)
∂28-Nov-84 0331 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Comments on the Preliminary Report (2 pages)
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Nov 84 03:31:05 PST
Received: from unc by csnet-relay.csnet id a021839; 28 Nov 84 6:30 EST
Received: by unc (4.12/4.7) id AA17493; Tue, 27 Nov 84 23:00:58 est
Date: Tue, 27 Nov 84 23:00:58 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8411280400.AA17493@unc>
To: scheme@mit-mc.ARPA
Subject: Comments on the Preliminary Report (2 pages)
Cc: willc%indiana.csnet@csnet-relay.arpa
Comments on Essential Scheme
These comments are arranged in four categories: lambda syntax, other
special forms, functions, and lexical matters. I feel quite strongly
about the issues I outline here. I have other minor gripes (don't we
all) that I didn't bother to include here, for fear they would water
down the substantive issues.
Lambda Syntax
For several years my Scheme system has had a syntax for lambda
expressions that allows naming of the closure within the body of the
closure for enhanced readability and efficiency. The syntax is:
(lambda name formals . body)
where name is a symbol bound lexically to the closure within body,
formals is a list of formal parameters, and body is a set of zero or
more forms to execute. Name may be omitted and there is no ambiguity
since formals is always a list.
This feature, which I have called "named lambda," allows terse,
referentially transparent recursive function definitions. It is similar
to the optional "rec," special form, but is shorter and perhaps more
easily optimized than rec. It is quite a bit shorter than using
"letrec." For example, the boring factorial function looks like:
(lambda fact (x) (if (= x 0) 1 (* x (fact (- x 1))))),
a totally self contained definition.
Named lambda generalizes to named let, something which seems to have
appeared elsewhere independently. It looks like:
(let name ((x1 v1) (x2 v2) ...) . body),
where name may again be omitted. It translates into:
((lambda name (x1 x2 ...) . body) v1 v2 ...),
and replaces the old iterate expression.
Unfortunately, the partial destructuring provided by the adopted lambda
syntax conflicts with the named lambda syntax, introducing an ambiguity
in some cases, as in:
(lambda f (g x) ...).
Is this a named lambda with two formals or an unnamed lambda with a
single &rest formal?
The partial destructuring syntax is merely a different syntax for the
&rest formal parameter adopted by Common Lisp. The only benefit to be
gained by not using the Common Lisp syntax is that some implementations
might generalize to full destructuring. I think it more likely that we
would want to generalize to optional arguments. Why not just use part
of the syntax adopted by Common Lisp? For now, we could make the &rest
syntax required and the &optional syntax optional.
If everyone dislikes the &rest syntax then I think we ought to resolve
the ambiguity with named lambda by requiring the name to be present.
This would improve code readability and facilitate optimization
regardless of the system the code is executed on.
Other Special Forms
1. The "if" special form should require an else part. This allows the
compiler/interpreter to make a sanity check for the user which might
save some grief, and seems a little cleaner. The macros "when" and
"unless" are the appropriate way to express the intended meaning.
2. Block is a much better name for the statement grouping special form
than "begin". Do we really need an artifact of Algol syntax in our
language? After all, it is a block of code, not a begin of code.
(If someone is worried about clashing with a process blocking function
they should name their function "block-process.")
3. Case expressions should allow single keys without putting them in a
list. The user rarely wants the single key to be a list (eq semantics
and all), so there really isn't any ambiguity. Since single keys are
probably the most common, case expressions will be less bulky.
For example,
(case x ((a) ...) ((b) ...) ((c d) ...) (else ...))
would simply be
(case x (a ...) (b ...) ((c d) ...) (else ...)).
Functions
1. Call/cc should be an alternative to call-with-current-continuation.
How are we ever going to get people to feel comfortable with something
so imposing that it requires 30 keystrokes to type in and takes up half
a line?
2. Transcendental functions should be required only in implementations
with floating point numbers, not just any implementation with numbers
other than integers. In particular, an implementation with rational or
interval arithmetic should not be bound to supporting transcendental
functions. (This was probably just a misstatement in Will's note.)
3. The length function should be generic, returning a value for all
reasonable arguments. There can still be individual functions list-
length, string-length, vector-length, and so on.
Lexical Matters
Scheme systems should be case sensitive. Let's not forget that symbols
have other uses than as Scheme identifiers. How can we implement
prolog-like variables in Scheme without being able to differentiate
between upper and lower case letters within the symbols? Does anyone
really still use an upper-case only terminal? Assuming case
sensitivity, all standard Scheme functions and special forms should be
written with entirely lower-case letters.
∂30-Nov-84 1658 RPG Re: Kent Dybvig's Comments on Scheme
∂30-Nov-84 1545 @MIT-MC:bartley%ti-csl.csnet@csnet-relay.arpa Re: Kent Dybvig's Comments on Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Nov 84 15:44:40 PST
Received: from ti-csl by csnet-relay.csnet id a008334; 30 Nov 84 18:12 EST
Date: 30 Nov 1984 1147-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: Kent Dybvig's Comments on Scheme
To: Scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa
Re: Kent Dybvig's comments on the preliminary report on Scheme
I'd like to briefly add my "votes" on Kent's suggestions and bring up
some additional complexities in the issues he raised.
Lambda Syntax
I prefer (REC name (LAMBDA args . body)) first, then MIT-style
NAMED-LAMBDA second. (I support both.) Will's discussion summarizes
my reasons quite well. We should NOT require all lambdas to be named.
IF without else part
I would not mind requiring WHEN in this case, making (IF a b)
syntactically incorrect. This allows better compile-time checking. I
use WHEN myself to make this distinction and find it useful. BTW, I do
NOT find UNLESS useful, since (WHEN (NOT ..)..) usually reads better.
BLOCK vs BEGIN vs LET()
As Will points out, the real question is whether the construct we have
in mind is a compound expression or an Algol-like block containing both
declarations and expressions to be evaluated. I prefer BEGIN for the
former and LET for the latter.
The problem is that Will suggests (paraphrasing someone else) that
(BEGIN ...) might be equivalent to (LET () ...). I have conflicting
thoughts on this. Pro: if they are the same, then I would vote to
remove BEGIN from the (essential) language as hopelessly redundant with
LET. Con: early papers by Steele and Sussman treat (BEGIN a b) as a
macro for ((LAMBDA (ignored-id) b) a), which is equivalent to
(LET ((ignored-id a)) b). Thus, BEGIN already is a scope-extending
operation.
This has the following practical consequence. What is the scope of FOO
in the following?
(define (f ...)
(define g ...)
(begin
(define foo ...))
body)
I understand that MIT Scheme "promotes" both G and FOO directly under
F. This hack is needed for macros that expand into multiple DEFINEs
and thus must be "wrapped" in something to be spliced in correctly.
If we define BEGIN in terms of LET, then the scope of FOO will have to
be confined to the scope of the BEGIN.
What should we do? I vote that BEGIN indicate a compound expression,
contrary to early Steele&Sussman, and that LET() be used for
Algol-style blocks.
CASE expressions with single keys
We will accept single keys in CASE expressions. If ELSE is to be a
single key in the last clause, however, it will have to be enclosed in
parentheses to avoid being interpreted as "otherwise".
CALL/CC
"CALL-WITH-CURRENT-CONTINUATION" is nonsense to the unititiated, too.
I will support both, but feel like it's silly to have the long name.
Must this be a procedure (e.g. a potential funarg) or can we treat it
as a special form?
Transcendental functions
What's the problem? Just call them "optional" as a group. What we've
been arguing is whether I have "true Scheme" if I have some kind of
representation for "real numbers" but don't support a certain set of
functions. This is irrational!! (sorry)
Generic LENGTH
I strongly abhor Common LISP-style genericity. As Will says, "generic"
operations on numbers with multiple REPRESENTATIONS is one thing, but
trying to be generic across different kinds of things is something
else.
Case-sensitive symbols
I feel very strongly that symbols, as processed by the reader, should
NOT be case sensitive and that (EQ? 'a 'A) be true. STRING->SYMBOL
should preserve case, however, and (EQ? '|a| '|A|) should be false.
-- David Bartley (Bartley @ TI-CSL)
-------
∂01-Dec-84 1049 RPG Kent Dybvig's Comments on Scheme
∂30-Nov-84 2036 @MIT-MC:JINX@MIT-OZ Kent Dybvig's Comments on Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Nov 84 20:35:53 PST
Date: 30 Nov 1984 23:35 EST (Fri)
Message-ID: <JINX.12067849164.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: Scheme@MIT-MC.ARPA
Subject: Kent Dybvig's Comments on Scheme
In-reply-to: Msg of 30 Nov 1984 12:47-EST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
BEGIN should certainly not add another contour. BEGIN is
equivalent to LET() if environments are not first class, but they are
in MIT Scheme. An incremental definition to the environment where the
subexpressions of the BEGIN expression are evaluated would have
different effects depending on whether a new contour was created or
not. I agree that BEGIN (for lack of a better name) should indicate a
compound expression and LET should be used for blocks.
Note that this is not contrary to all early Scheme papers
since in the Revised Report,
(BLOCK X Y) = ((LAMBDA (A B) (B)) X (LAMBDA () Y)).
X is evaluated in the environment where the BEGIN
expression appears, and Y is evaluated in an environment where no
bindings have been added. In a dialect without first-class
environments and without internal definitions, the environment where Y
is evaluated is the same as that where X is evaluated, thus no
contours have been added.
I think that there are only two valid reasons for adding
special forms:
- They provide a convenient syntax for something which
could be expressed only considerably more clumsily without them.
Example: COND (as compared to nested IFs). These are usually macros
which expand into the clumsier form.
- They provide an extension to the language which requires
special handling by the interpreter or compiler. Their effect could
otherwise not be achieved. Example: QUOTE. These are the "TRUE"
special forms.
I don't think that CALL-WITH-CURRENT-CONTINUATION falls in
either class, so there is no need to make it a special form. Besides,
a portable program would not be able to rename it since we have not
specified a way for adding syntactic extensions.
Allowing IF not to have an alternative sub-expression is
convenient because it is clear and eliminates the need for WHEN,
another special form. I don't like the proliferation of special forms
and would object strongly to requiring another one for this purpose.
I can't see that there is a difference between WHEN and IF in terms of
compile-time checking. IF with two subexpressions and IF with three
subexpressions can be treated as different beasts.
I agree with the remaining three points.
- Bill Rozas (JINX@MIT-MC)
∂05-Dec-84 1353 RPG Re: Kent Dybvig's Comments on Scheme
∂04-Dec-84 2015 @MIT-MC:HUDAK@YALE.ARPA Re: Kent Dybvig's Comments on Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 4 Dec 84 20:15:10 PST
Received: by YALE-BULLDOG.YALE.ARPA; 4 Dec 84 11:49:28 EST (Tue)
Message-Id: <8412041649.AA04845@YALE-BULLDOG.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Tue, 4 Dec 84 11:37:43 EST
Subject: Re: Kent Dybvig's Comments on Scheme
Date: Tue, 4 Dec 84 11:37:46 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: Bill Rozas <JINX%MIT-OZ@MIT-MC>
Cc: Scheme@MIT-MC, Hudak@YALE.ARPA
In-Reply-To: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>, 30 Nov 1984 23:35 EST (Fri)
Not having participated in the workshop, I've been hesistant about
making comments on the various issues flying by recently, but I couldn't
resist responding to Bill Roza's comments on special forms:
I think that there are only two valid reasons for adding
special forms:
- They provide a convenient syntax for something which
could be expressed only considerably more clumsily without them.
Example: COND (as compared to nested IFs). These are usually macros
which expand into the clumsier form.
- They provide an extension to the language which requires
special handling by the interpreter or compiler. Their effect could
otherwise not be achieved. Example: QUOTE. These are the "TRUE"
special forms.
I think there's one other reason, which in a sense subsumes the first:
*readability*. In particular, with regard to IF having or not having
an alternative sub-expression, I find that when I'm reading code and
come across an IF expression, I look very hard to see if it has an
alternative branch. If it doesn't, I look again to be sure I didn't
miss it. I think this "convenient feature" degrades readability.
I agree with Bill Rozas that one shouldn't proliferate special forms,
but my reason is that they are typically complex, and their syntax
becomes hard to remember. However you can't get much simpler than
WHEN and UNLESS. Their use, in my opinion, greatly enhances
readability.
- Paul Hudak (hudak@yale)
∂07-Dec-84 1341 RPG [willc: preliminary report of workshop]
∂06-Dec-84 1909 KMP@MIT-MC [willc: preliminary report of workshop]
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 6 Dec 84 19:09:23 PST
Date: 6 December 1984 22:02-EST
From: Kent M Pitman <KMP @ MIT-MC>
Subject: [willc: preliminary report of workshop]
To: willc%indiana.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
In-Reply-To: <8411120256.AA05811@iuvax.UUCP>
Ok, Will, I'm assuming things decided at the meeting are not cast in
concrete. I certainly take issue with a number of the decisions.
In a few places, I also pick on your notation a bit when I think
its unclear. Thanks for taking the time to write up everything.
Here come the comments...
* I dislike the description of "optional features". In particular,
you say:
Optional features may not be supported by every implementation,
but those that do support a feature will use the same syntax and
semantics for the feature. Hence code that makes use of optional
features will run on any implementation of Scheme that supplies
the optional features.
....
An implementation may extend the language in any way whatsoever,
but code that makes use of extended features is not portable.
These two paragraphs are in conflict and allow for lots of
inconsistency which I will identify at appropriate points later.
The principle troubles, though, are:
* Since a language can be extended in "any way whatsoever",
can such extensions be syntactically in conflict with optional
language features? eg, if #\ is optional and my dialect doesn't
use it, can I then define my own #\ as an extended part of the
required subset?
* In some cases, "required" language features can be redefined
incompatibly by "optional" features. eg,
(COND (FOO => X))
has a well-defined semantics regardless of whether the optional
"=>" feature of COND is present. However, that semantics is not
the same in the two cases.
The point I'm trying to make is that saying something is "optional" says
little if anything unless you at least define that if anyone uses the
syntax corresponding to the optionality in a dialect which doesn't support
the feature, that he is in error. Put another way, extensions may not
invalidate optional features. On the other hand, if this were stipulated
the list of "optional" features to which I objected would be quite lengthy.
* I disagree with calling the string quote character "double quote".
I prefer "doublequote". Since there is a character named "quote", the
phrase "double quote" might designate '' instead of ".
* In discussing what terminates tokens, you should say which of these
characters (presumably all) are also single-character tokens. In
particular, that "((A B)C)" is tokenized
{"(" "(A" " " "B" ")C" ")"}
or {"(" "(" "A" " " "B" ")" "C" ")"}
hangs in the balance. I'm sure no one disagrees, but if you're not going
to be complete about these things, you are sort of wasting your time
just trying to look formal about things.
* I agree with reserving {, [, ], and }, but I would specify that they
may be used as alphabetic according to syntactic escape conventions.
Optionally, the following characters may be delimiters that
terminate symbols:
* What does it mean to say single quote, backquote and sharpsign
may "optionally" terminate tokens? It means expressions
like (JOHN'S COAT) read differently in the different dialects. How
is this distinct from saying "Optionally, the following characters
may be delimiters that do not terminate symbols:"? It only makes
sense to say something is optional if it's going to mean that when
it's present. I bet some dialects treat (JOHN'S COAT) as a two-list
and others treat it as a three-list. Hence, any description of this
relation between dialects can at best say: "The specification takes
no stand on the issue of whether the following delimiters terminate
symbols. Any use of expressions like (JOHN'S COAT) are to be considered
non-portable."
* I would personally prefer if vertical bar had been defined to be
alphabetic, but I am at least happy that it is "not specified" what
its meaning is rather than that it is "optional".
* I strongly oppose the idea of not specifying an escape char for
symbols. You say there is "widespread agreement that ``slashification''
of characters within symbols is a relic that ought to be abandoned."
I am not party to such agreement.
I strongly oppose the idea of eliminating slashification. The Maclisp
conventions of vertical bars made up for the absence of strings. With
their passing, syntactic quoting of lots of chars is very rare, and
in those few cases, I think slashing works fine. It also is a low-cost
mechanism for the printer, since no lookahead is required. Also, it is
uniform with respect to strings, which already use slash for special
chars anyway. Finally, without slash, there would be no way to get
vbars into symbol names, since vbars cannot adequately quote themselves.
On the other hand, slash can work fine in the absence of vbar. So if
one thing is to go as a readsyntax quoter, it should be vbar.
* Will-- Your meta-syntactic use of "..." in a description of what
the "." character does is very confusing.
* Does anyone mind if (. A) is the same as A? It has a certain elegance
to it if you think about it.
(CONS 3 (CONS 2 (CONS 1 0))) => (3 . (2 . (1 . 0))) => (3 2 1 . 0)
(CONS 2 (CONS 1 0)) => (2 . (1 . 0)) => ( 2 1 . 0)
(CONS 1 0) => (1 . 0) => ( 1 . 0)
0 => 0 => ( . 0)
Just a thought.
* I find #!true and #!false to be ugly and visually confusing
with the popular convention of "!" designating something
destructive. It would make more sense for #! to be saved for
something like #. in Common Lisp. I agree #<something>TRUE
is reasonable. I'd have preferred #: for this.
* What does it mean to say:
"Optionally, binary numbers may be written using the #b notation.
Optionally, octal numbers may be written using the #o notation.
Optionally, decimal numbers may be written using the #d notation.
Optionally, hexadecimal numbers may be written using the #x notation."
Presumably this means that dialects not wanting #B, #O, etc. can
use these to mean other things.
* What does it mean to say:
"Optionally, special characters may be written using the #\
notation. If this feature is supported, then the Common Lisp
names for special characters must be supported."
Presumably this means that if I don't want to be able to write special
characters, I can make #\ do something else. In fact, if I want to
use other names than those used by Common Lisp, I can just "not support"
this feature and then "make any extension whatsoever" to my dialect
such that #\ does something completely different, like understand
a different set of character names.
* Was anything decided about whether #!TRUE and #!FALSE would self-evaluate
or whether they required quoting?
* Was anything decided about whether numbers must self-evaluate or
whether a dialect may require quoting?
* Since "optionally, numbers may be written using decimal points and/or
exponents", does this mean that numbers with decimal points are integers
or floating? Does it mean that if I don't support the feature that
I can take the alternate position?
* I notice that the space of symbol names is highly constrained for
the "required subset". A property, however, that should be required
is that within any given dialect, every interned symbol (no matter what
characters it contains) must have a printed representation which is
read-invertable within that dialect. I suspect that all dialects
do this already anyway, but it should be a guaranteed property of the
language since programmers will tend to depend on such things and should
have a guaranteed semantics backing them up.
* What does it mean to make NIL optionally evaluate to the empty list
or optionally evaluate to false. What happens if I make it false and
then try to run my code in another dialect where it's the empty list
and where the two are not the same thing. The definition of optionality
says that code written in the optional subset will run correctly in
another dialect supporting optional features. It doesn't seem to me
like a good idea to optionally define a symbol as able to take on several
values and then be able to write meaningful code.
* It is specified that "the order of evaluation within an application
is not specified". I would prefer "combination" or "expression" to
"application" as a matter of terminology to avoid confusion with the
application that happens in the APPLY function, which doesn't involve
evaluation at all.
* I don't like the name LETREC; I preferred LABELS. Neither is very
suggestive of anything; the latter is at least a real word.
* Will-- I don't like the use of the term "mistake" throughout the report,
at least without defining it formally. In my dialect, it connotes
an unintentional error and it seems to me that if the user
intentionally did the offending thing, it would not be a mistake.
I would say "error" in its place, or define the term "mistake"
formally early on.
* I disagree with the various forms that claim it to be a "mistake"
to use certain return values, allowing some implementations to
signal an error. I don't agree that such errors can ever be
detected at the language level; I would like a formal description
of exactly when it is believed that such an error could be signalled.
The forms in question are: IF, COND, SET!, DEFINE, DEFINE!, CASE,
SET-CAR!, SET-CDR!, and VECTOR-SET!.
* The semantics of (COND (X => Y)) is messy due to optionality as
described earlier.
* Will-- I would name the ... sequences in definitions of things
like LET, COND, etc which use multiple sequences. I realize you
use them right to left, but that could be made more apparent.
Perhaps ..foo.. instead of ...
* I find the name SET! both ugly and redundant. The "!" convention
as originally created by the T people identifies a destructive
variant of an otherwise-non-side-effecting operation. So, for
example, APPEND and APPEND!, etc. Logically, there could be a
CHANGE-CAR and CHANGE-CAR!, one of which was
(LAMBDA (C V) (CONS V (CDR C)))
and the other which was
(LAMBDA (C V) (SET (CAR C) V) C)
In any case, I strongly think that the primitive for assigment
should be SET and not SET!. In fact, since no one likes assignment
anyway, I don't see any reason why anyone should object to just
leaving this undefined in the standard. It would only discourage
people from writing destructive code. But I would be very unhappy
to see T change the name of SET to SET!. Similarly, I strongly
dislike the name SET-CAR! and SET-CDR!.
* The definition of DEFINE refers to the "top-level" definition of
a variable. I don't believe it's established what "top-level" means,
so this definition is pretty muddy. Further, what is the implication
of this definition upon doing (LAMBDA (X) (DEFINE X X))?
I am very discouraged that the (DEFINE (fn . args) ...) syntax isn't
required. This means that any portable code must be ugly, meaning
no one is likely to ever write truly portable code, meaning this
standard is a farce.
* It is silly to require that there be at least one form in a (BEGIN).
It is easy for macros to come up with situations where there are
no forms to put there and as long as the macro's caller doesn't
depend on the value, it shouldn't matter. The return value of a
BEGIN with no forms should just be undefined.
* The fact that (LET* ...) cannot admit an optional name reveals an
asymmetry which I find very distasteful. I suggest that named LET
be left to implementors as an "arbitrary" extension not to be mentioned
in any common subset.
* I would prefer to have REC be called LABEL. Again, at least it's English.
* I don't see any good reason to have DO not bind RETURN. Can someone
elaborate on that?
* The description of DEFINE inside LAMBDA is inconsistent with the
earlier description of DEFINE as creating a toplevel definition.
I think this should be a non-standard extension. I see no reason to
dignify it with any "optional" status.
* The term "top-level binding" is again completely vague in DEFINE!'s
definition.
* The definition of optionality specified that if an optional feature
was present, the dialect should prefer to call it by the "optional"
name. This is somewhat inconsistent with making SEQUENCE an optional
synonym for BEGIN. Since it is not encouraged for use and is not going
to exist in all dialects, is there any sense to including it here?
* The entire section on datatypes is hopelessly muddled. About the only
useful thing said is that anything which is a first class object must
have unlimited extent.
* In the sentence "There is an object which represents both false and
the empty list", I cannot discern whether that means there may/must
be one/two objects filling that description. Shouldn't we say,
"False and the empty list must be represented as first class objects
and that object {may,must} [not] be distinct." or some such.
* Since datatypes are not declared to be disjoint, it isn't necessary
to mention that characters may be represented as numbers, except perhaps
as a footnote to remind the forgetful reader. Strings can be represented
as numbers, too, the way things are written.
* Was there really anyone who thought streams shouldn't be first class
objects? Since datatypes aren't disjoint and such objects could be
indistinguishable from numbers or arrays or whatever, is there really
a reason to care?
* The unary procedure not should be defined to return "a true value if
its argument is false and a false value if its argument is not false."
... rather than "if its argument is true." for the second part.
* I suggest renaming CALL-WITH-CURRENT-CONTINUATION (or CALL/CC) to just
CONTINUE. eg,
(CONTINUE (LAMBDA (C) (IF (FOO) (F C) (G C))))
Anyone else support this?
* By the way, saying the escape procedure has unlimited extent doesn't say
it can be called more than once. Does everyone agree to either stipulate
that or not?
* If "the unary predicate NUMBER? is true of numbers and false of
everything else" and "the unary predicate INTEGER? is true of
integers and false of everything else", I don't suppose this says
much since types are not disjoint and so strings are not necessarily
not numbers and need not necessarily cause INTEGER? or NUMBER? to
return false. Certainly characters needn't yield false from NUMBER?
or probably from INTEGER?. As such, these predicates are of limited
value.
* Of what point is it to make claims about what "almost all implementations"
will do for real numbers? Either they're required to or they aren't.
The rest belongs in some other document.
* I don't agree that allowing generalization of +, -, *, and / to arbitrary
arity is a good idea or even well-defined. eg, the proper generalization
of - to arity 1 is (- 3) => 3, not (- 3) => -3. Hence, specifying that unary
negation is optional is in conflict with specifying that - may be generalized.
* Will-- The discussion of QUOTIENT/REMAINDER and of CONS/CAR/CDR should
use the word "respectively" in the appropriate places. When I first read
that QUOTIENT and REMAINDER return the quotient and remainder, I spent
an unduly long time flipping back pages looking to see if you'd allowed
multiple values before I realized that it was silly for both these functions
to do the same thing or for that same thing to be what it had first looked
to me like they're doing.
* I don't see why MIN/MAX should be restricted from arity 0. They should
just return the smallest and largest representable numbers. I guess as
long as they aren't defined to signal an error in this case, individual
dialects could be extended anyway.
* It should be made explicit whether (= 1 1.0) is defined to work. Note that
this may be tricky since even (= 1.0 1.0) won't necessarily work if the
1.0's were computed rather than read and have different bit patterns that
are too tiny to make a difference on output.
* It is silly to specify that implementations may "optionally" support
numbers that are non-integers. Why not just define that (NUMBER? x)
doesn't imply (INTEGER? x). That definition wouldn't mean that
every number wasn't an integer, it would only mean that every number
wasn't necessarily a number.
Specifying that "almost all implementations" will support this option
is again silly and might in pathological situations be misleading.
* Is the definition of (TRUNCATE x) really correct? It looks like it must
be screwed up on the negative side near 0. eg, (TRUNCATE -0.5) doesn't
have the same sign as 0.5 does it? Or is there a negative 0?
* The meaning of "interning" a symbol should be specified.
* It should be stated explicitly that CAR and CDR of the empty list
is not defined.
* What's this nonsense about pairs being maybe indistinguishable from
vectors of length 2. Is there a good reason for that? It doesn't really
matter since numbers haven't been defined as distinguishable from
strings either, but it somehow offends my sense of aesthetics to see
this note here. Is this due to some problem with Maclisp HUNK2's or
something unrelated?
* In "The following descriptions use the notion of a proper list. The
set of proper lists is the smallest set satisfying:
the empty list is a proper list
a pair x whose CDR is a proper list is a proper list,
provided (MEMQ x (CDR x)) is false."
I think MEMQ isn't the function that you want, but I find it amusing
to see the language defined meta-circularly in this way (since MEMQ
is almost certainly defined to terminate only on proper lists and may
even want to type-check proper-list-ness).
* Is the function LENGTH defined to err or to not return when given
a circular list? What about an otherwise improper (ie, dotted) list?
* The definition of APPEND is poor. It should be defined with NAMED-LAMBDA
for safety in situations where APPEND gets redefined. Also, its text
description is too windy.
* I see no reason for APPEND! to be defined to possibly side-effect
either arg. This may force lots of needless copying in order to write
provably correct programs. I can't imagine a definition of APPEND!
which would want to destructively modify its last argument.
* All these definitions (APPEND, REVERSE, ...) are ugly due to the
silly restrictive version of DEFINE. I certainly wouldn't want my
students programming like that.
* It should be stated in English what happens if LIST-REF and LIST-TAIL
fall off the end. I assume it follows from the definitions of CAR/CDR
that such is a signallable error.
* There should be MEMQ?, MEMV?, and MEMBER? to match MEMQ, MEMV, and
MEMBER. This enhances garbage collection since if these functions
are only being used for truth value, you don't want to hold pointers
to potentially large list structures. Also, it enhances debugging since
if F is a function on booleans, (F (MEMQ X Y)) will receive true/false
rather than a list or false. Ditto for ASSQ?, ASSV?, and ASSOC?.
* You specify no order of evaluation for MAPCAR. I think you mean no
order of "application".
* I dislike the asymmetry between MAPCAR and MAPC.
MAPC has no defined return value, MAPCAR does.
MAPC has defined order of application, MAPCAR does not.
In short, they have nothing really in common other than they type
of their args. I think they should not be named so similarly.
* I oppose the names MAPCAR and MAPC.
T calls these MAP and WALK, respectively.
The generic form of MAPCAR, which is the only thing for which
arbitrary order of application would make sense (since lists are
only sequentially accessible anyway), has no business being called
MAPCAR.
* With respect to the questions about VECTOR->LIST, I think the
right thing to say is that the conses it returns are mutable,
not that the result is necessarily a "new object", since if the
result is the empty list (eg, from an empty vector), I wouldn't
want the implication to be that
(NOT (EQ (VECTOR->LIST #()) (VECTOR->LIST #())))
since it follows from that that more than one false value must
(rather than "may") be possible.
* What happens if VECTOR-REF is out of range?
* VECTOR-SET! is ugly. It should at least be called SET-VECTOR-REF!
for symmetry with the other SET- things. Personally, I hate the
! and would strongly prefer just SET-VECTOR-REF.
* The relation between OBJECT-HASH and the GC should be specified.
Do things get GC'd if no other pointers exist to them? Also, it
might help to distinguish this kind of "hash" from the number that
comes from SXHASH in Maclisp. It took me a second to realize you
weren't talking about that.
------- End undelivered message -------
------- End undelivered message -------
∂07-Dec-84 1342 RPG Slashification
∂07-Dec-84 1327 JAR@MIT-MC Slashification
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 7 Dec 84 13:27:00 PST
Date: 7 December 1984 16:26-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: Slashification
To: KMP @ MIT-MC
cc: SCHEME @ MIT-MC
In-reply-to: Msg of 6 Dec 1984 22:02-EST from Kent M Pitman <KMP>
I think I was the one who suggested that there be neither slashification
nor vertical barring. If you tell the T printer not to use either \ or
| and it comes across a symbol which requires quoting anyhow, it prints
#[Symbol "foo"]. (If you have \ but not |, as in T, you need to have a
way to print the null symbol anyhow; it really does come out as #[Symbol
""] - try it.) If print tables exist or if STRING->SYMBOL accepts any
string whatsoever, then it is necessary to have some way for unusual
symbols to read and print, but there's not really any need to wire down
a special character for the purpose, because e.g. some # syntax could be
used.
Some people wanted to throw away \ in favor of just | ; people didn't
agree when I suggested going with \ but not | ; so we just decided that
the need was unimportant enough that neither syntax was required. I'm
not convinced that there needs to be a defined, portable way to print
unusual symbols, although maybe you could talk me into such a position.
Jonathan
∂09-Dec-84 1252 RPG MIN/MAX, DO/RETURN
∂08-Dec-84 1556 KMP@MIT-MC MIN/MAX, DO/RETURN
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 8 Dec 84 15:56:47 PST
Date: 8 December 1984 18:55-EST
From: Kent M Pitman <KMP @ MIT-MC>
Subject: MIN/MAX, DO/RETURN
To: SCHEME @ MIT-MC
References: Msg of 6 Dec 1984 22:02-EST from Kent M Pitman <KMP@MIT-MC.ARPA>
Jonathan Rees had a good points about a couple of my earlier remarks...
* Making MIN/MAX return smallest/largest representable number would
be infeasible in implementions with bigfloats or bignums. I should
have thought of that. (I must have been thinking too hard about
the flonum case; sorry.) I'll withdraw that suggestion.
* Making DO bind RETURN would have been a bad idea since it would "wire"
the name RETURN. I withdraw my disparaging remarks about its not binding
that name.
-kmp
∂09-Dec-84 1304 RPG Re: critique of preliminary report
∂09-Dec-84 1142 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Re: critique of preliminary report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Dec 84 11:42:25 PST
Received: from indiana by csnet-relay.csnet id a022287; 9 Dec 84 14:34 EST
Received: by iuvax.UUCP (4.12/4.7)
id AA06716; Sat, 8 Dec 84 22:50:32 est
Date: Sat, 8 Dec 84 22:50:32 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
To: KMP@mit-mc.ARPA
Subject: Re: critique of preliminary report
Cc: scheme@mit-mc.ARPA
I am posting this in response to Kent Pitman's excellent critique
of the preliminary report on the October workshop.
ERRORS AND OVERSIGHTS
I should have said:
Numbers, strings, characters, and #!TRUE and #!FALSE are
self-evaluating, which means they need not be quoted. Symbols and
pairs are not self-evaluating. It is not specified whether other
things are self-evaluating.
The semantics of (BEGIN) is not specified.
TRUNCATE could be defined by
(DEFINE TRUNCATE
(LAMBDA (X)
(IF (NEGATIVE? X)
(- 0 (FLOOR (ABS X)))
(FLOOR X))))
VECTOR-REF takes a vector v and an nonnegative integer n such
that n < (VECTOR-LENGTH v) and returns ... .
----------------------------------------------------------------
WHAT DOES "OPTIONAL" MEAN?
The intent of the workshop was that extensions must not conflict
with optional features, and I should have said so. In fact some
features were made optional in order to prevent dialects from
using certain syntaxes for other purposes. It follows that #b,
#o, #d, #x, #\, and so on can't be used for any purpose other
than to support the optional feature.
I agree that the "optional" stuff about NIL and T is ridiculous.
What I should have said instead is that implementations that want
to treat NIL and T as constants can do so. In effect this is a
warning against using NIL and T to name variables. Note that
(FOO . NIL) cannot read the same as (FOO) no matter what.
I didn't mean to say that "optional" names or features are to be
preferred to essential names or features, and I don't think I did.
----------------------------------------------------------------
POOR WRITING IN THE PRELIMINARY REPORT
I agree with Kent Pitman's points regarding the use of "...",
"mistake", "respectively", and "double quote".
I agree that the set of single character tokens needs to be
better defined. I would like to include appendixes in the final
report with more rigorous descriptions of the lexical syntax, the
context-free syntax, and the denotational semantics of Scheme.
How about "The order of evaluation within a procedure call is not
specified"? That isn't quite true, of course -- normal order
evaluation is prohibited.
I should have said that some single object represents both false
and the empty list. There may be other objects representing
false. Might there be other objects representing the empty list?
(I hope not.)
I agree that it would be better to have said that (NUMBER? x)
doesn't imply (INTEGER? x).
I hope everyone noticed that it is an error to take the CAR or
CDR of the empty list.
The definition of a proper list in the preliminary manual was a
joke. The notion of a proper list has to do with finiteness,
which is not first order definable.
----------------------------------------------------------------
LEXICAL MATTERS
It is not specified whether single quote, backquote, sharp sign,
and vertical bar are delimiters that terminate symbols. The
status of these characters would be decided by a general rule
that emerged during discussion at the workshop, but not everyone
agreed to the general rule. The general rule is: Special
characters that come in pairs (left and right parenthesis, left
and right bracket, left and right curly brace, doublequote)
should be delimiters while other special characters (period and
so on) should be preceded by a space if they are to be used in
their special sense. Semicolon isn't really an exception to the
pattern because the end of line would be a delimiter anyway.
Whether vertical bar should be a delimiter according to the rule
depends on whether vertical bar is a special character that comes
in pairs, which is not specified. According to the rule single
quote, backquote, and sharp sign should not be delimiters.
> * I agree with reserving {, [, ], and }, but I would specify that they
> may be used as alphabetic according to syntactic escape conventions.
I don't understand "...according to syntactic escape conventions".
I have yet to hear of a good use for slashification of symbols.
If there is no compelling need for a feature, we should leave it
out. The workshop allowed slashification but did not encourage
it.
> * I notice that the space of symbol names is highly constrained for
> the "required subset". A property, however, that should be required
> is that within any given dialect, every interned symbol (no matter what
> characters it contains) must have a printed representation which is
> read-invertable within that dialect. I suspect that all dialects
> do this already anyway, but it should be a guaranteed property of the
> language since programmers will tend to depend on such things and should
> have a guaranteed semantics backing them up.
We probably ought to require something along these lines, but the
property you desire is too strong. It is enough that every
symbol read by the reader be printed in a form that will read
back in as the same symbol. Other symbols are too random to
worry about. In fact, I would be satisfied if only the required
set of symbol names have the property you desire. For what it's
worth, Franz Lisp does not have the property, but I doubt that
its lack is a significant cause of dissatisfaction with Franz
Lisp.
----------------------------------------------------------------
SPECIAL FORMS
LETREC vs LABELS, REC vs LABEL, and SET vs SET! are matters of
taste that needed to be decided one way or the other, and were.
History plays a significant role in decisions such as these. The
first two matters had history on both sides, but the history of
SET in traditional Lisp counts against it.
In some cases the IF, COND, and CASE special forms return
unspecified values. The SET!, DEFINE, and DEFINE! special forms,
and the SET-CAR!, SET-CDR!, and VECTOR-SET! procedures, always
return unspecified values. Except for the result of the DEFINE
form, I wrote that it is a "mistake" to use these undefined
values, and except for the results of the DEFINE and DEFINE!
forms I wrote that implementations could signal an error if the
values that were returned were "used". What I wrote is faithful
to the workshop's decisions, but I can be accused of deviating in
the cases of DEFINE and DEFINE! .
Kent is right to question what we meant by "using" a value. The
answer is that we don't know. Obviously an implementation could
return a strange value that would cause an error to be signalled
if an attempt were ever made to take its CAR or its successor; an
implementation could also arrange for an error to be signalled if
the value were ever an operand to EQ? or CONS; and there are no
doubt other things that an implementation could do as well. I
will not offer a formal description of the circumstances under
which an error could be signalled, because I want to leave room
for implementations to experiment with different approaches.
A DEFINE form is at "top level" iff it it not nested within any
other form. This definition clearly establishes circumstances
that do not count as top level, but it does not establish any
circumstances that do count as top level. I think each
implementation will have to specify circumstances under which a
DEFINE form has the described semantics, and those circumstances
would then count as top level for that implementation.
The Abelson and Sussman book uses DEFINE inside LAMBDA as
syntactic sugar. Scheme's future is tied to the success of that
book, so the sugar was dignified with "optional" status. The
optional status of the sugar required that ordinary DEFINE be
restricted to "top level".
The (DEFINE (fn . args) . body) sugar was dignified with
"optional" status for the same reason. Kent has acquired a taste
for this sugar, but I consider it a violation of orthogonality
that is doubly pernicious: (1) it discourages programmers from
thinking of procedures as objects distinct from their names; (2)
it discourages programmers from using procedures with local
state.
I agree that the optional status of named LET should imply an
optional status for named LET*, or else both named LET and named
LET* should be left out altogether. By the way, David Bartley
asks whether the body of a named let is within the scope of the
name. The Revised Report has the body within the scope of the
name. Does anyone want to argue that the body should be outside
the scope of the name?
When it was asked if DO should bind RETURN, someone said "Of
course not!", and that was the end of the discussion. If DO were
to bind RETURN I believe that DO would be the only construct in
even the optional language to bind an identifier that does not
appear explicitly in the code, and I see no reason to condone
that kind of anomaly.
----------------------------------------------------------------
DATATYPES
I was disappointed that we were unable to agree that any
datatypes were disjoint. The fact that the workshop participants
insisted on a special note to the effect that characters need not
be a distinguishable data type leads me to believe that despite
their votes most participants assumed that other data types were
distinguishable. In the final report I intend to recommend that
at the very least numbers, symbols, and pairs should be disjoint;
does anyone object?
Even without disjointness of data types, the NUMBER? and INTEGER?
predicates are useful because they define the domains of other
procedures. Thus if all strings are numbers then it must be
possible to subtract strings.
The nonsense to the effect that pairs might be indistinguishable
from vectors of length 2 is to remind folks not to assume that
pairs and vectors are disjoint. I agree that the note is out of
place and ugly.
I expect streams will be a Scheme data type, but as Kent points
out they might overlap with (say) numbers. Nonetheless the
STREAM? predicate will be useful because anything of which the
STREAM? predicate is true will have to support the operations on
streams.
----------------------------------------------------------------
PROCEDURES
I think it went without saying that escape procedures can be
called more than once. We didn't feel any need to say that the
addition procedure could be called more than once, either.
The generalizations of +, -, *, and / to arbitrary arity must
follow Common Lisp, so the ambiguity is not great. There is some
ambiguity, however, because Common Lisp has all sorts of rules
about integers, rationals, floats, and complexes that don't apply
to Scheme.
MIN and MAX are restricted from arity 0 because some
implementations don't have a smallest or largest representable
number.
Implementations should not be allowed to signal an error on
something like (=? 1 1.0). I don't think we should specify that
the result is true because you might want to implement a Scheme
in which "approximations" are a subtype of the numbers, in which
1.0 is read in as an approximation, and in which all equality
comparisons involving approximate numbers return false.
(If you haven't caught on by now, I'm perfectly comfortable with
the fact that Scheme is far less tightly specified than Common
Lisp. I believe Scheme can continue to represent the future of
Lisp only by being open to experimentation.)
I would rather not talk about "interning" a symbol, because
there is no need to talk about it when all symbols are interned.
I have to use words like "interned" to talk about implementations
in which not all symbols are interned, but for definitions I
would like to refer people to manuals for traditional Lisps.
LENGTH is defined on proper lists, and its action on anything
else is not specified.
I can't imagine a definition of APPEND! that would want to mutate
its last argument either. Shall we say it doesn't?
Kent's suggestions for MEMQ?, MEMV?, MEMBER?, ASSQ?, ASSV?, and
ASSOC? are interesting. Several people at the workshop, notably
Hal Abelson, expressed the belief that we ought to reconsider the
entire MEMBER/ASSOC complex of procedures.
MAPCAR and MAPC have their historical names for historical
reasons, and I would not be averse to renaming them eventually.
If MAPCAR is defined as follows in an implementation that
evaluates right to left, then the list of results is constructed
from right to left:
(DEFINE MAPCAR
(LAMBDA (F L)
(IF (NULL? L)
'()
(CONS (F (CAR L)) (MAPCAR F (CDR L))))))
I agree with Kent that the result of VECTOR->LIST cannot
reasonably be guaranteed to be a new object.
VECTOR-SET!, SET-CAR!, and SET-CDR! seem inconsistent to me too.
I think we should offer a prize for the best rationalization of
these names.
I think garbage collection should be treated as an issue of
performance rather than as an issue of semantics.
Peace, William Clinger
∂09-Dec-84 1307 RPG apology to Franz Lisp
∂09-Dec-84 1145 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa apology to Franz Lisp
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Dec 84 11:44:54 PST
Received: from indiana by csnet-relay.csnet id ab22287; 9 Dec 84 14:36 EST
Received: by iuvax.UUCP (4.12/4.7)
id AA01074; Sun, 9 Dec 84 11:11:13 est
Date: Sun, 9 Dec 84 11:11:13 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
To: scheme@mit-mc.ARPA
Subject: apology to Franz Lisp
I apologize to Franz Lisp for claiming that not every interned symbol in
Franz has a printed representation that reads back in as the same symbol.
An example confused me but not Franz Lisp.
Peace, William Clinger
∂10-Dec-84 1123 RPG Scheme conference report
∂09-Dec-84 1648 @MIT-MC:ANDY@SU-SCORE.ARPA Scheme conference report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Dec 84 16:48:24 PST
Date: Sun 9 Dec 84 16:45:14-PST
From: Andy Freeman <ANDY@SU-SCORE.ARPA>
Subject: Scheme conference report
To: scheme@MIT-MC.ARPA
Will the final report on the scheme conference say anything about
macros? There are substantial issues to be resolved/understood,
especially in scoping and expansion, but can a "least common
denominator" solution be released in the interim? How about a syntax
for defining top-level macros? That can be useful even if everything
else is undefined or optional.
Speaking of top-level solutions, why was ",." left out of the
backquote syntax? (It's like ",@", except that the value of the
following form may be destructively spliced into the result. ",@", as
you recall, non-destructively splices the value of the following form
into the result.) If deeper levels of nesting are going to be
optional, the report has to define what happens.
By the way, unless Scheme is going to define a character set, EOF
isn't necessarily a character. Neither is end-of-line.
Are all symbols interned or not? (Interning isn't necessary to print
code and be able to read it back in later.)
Still, most of these are minor issues. What the final report really
needs is a discussion of the decisions. Some things do not need
explanation (except to historians), like the names lambda and ', but,
for instance, why are true and false self-evaluating? In many cases
the decision itself is unimportant, but the issues are.
The report would also be improved by explicit mention of controversial
issues. So there's no decision; the reasons are still important.
-andy
ps - Why is argument evaluation order unspecified? That was a mistake
in Pascal, but then AND/OR/etc. have a defined order in Scheme. Then
again, so many standard forms have a right-left defined order that
consistency would suggest that user procedures should also.
Is the closure position an argument?
-------
∂10-Dec-84 1137 RPG Scheme conference report
∂09-Dec-84 1648 @MIT-MC:ANDY@SU-SCORE.ARPA Scheme conference report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Dec 84 16:48:24 PST
Date: Sun 9 Dec 84 16:45:14-PST
From: Andy Freeman <ANDY@SU-SCORE.ARPA>
Subject: Scheme conference report
To: scheme@MIT-MC.ARPA
Will the final report on the scheme conference say anything about
macros? There are substantial issues to be resolved/understood,
especially in scoping and expansion, but can a "least common
denominator" solution be released in the interim? How about a syntax
for defining top-level macros? That can be useful even if everything
else is undefined or optional.
Speaking of top-level solutions, why was ",." left out of the
backquote syntax? (It's like ",@", except that the value of the
following form may be destructively spliced into the result. ",@", as
you recall, non-destructively splices the value of the following form
into the result.) If deeper levels of nesting are going to be
optional, the report has to define what happens.
By the way, unless Scheme is going to define a character set, EOF
isn't necessarily a character. Neither is end-of-line.
Are all symbols interned or not? (Interning isn't necessary to print
code and be able to read it back in later.)
Still, most of these are minor issues. What the final report really
needs is a discussion of the decisions. Some things do not need
explanation (except to historians), like the names lambda and ', but,
for instance, why are true and false self-evaluating? In many cases
the decision itself is unimportant, but the issues are.
The report would also be improved by explicit mention of controversial
issues. So there's no decision; the reasons are still important.
-andy
ps - Why is argument evaluation order unspecified? That was a mistake
in Pascal, but then AND/OR/etc. have a defined order in Scheme. Then
again, so many standard forms have a right-left defined order that
consistency would suggest that user procedures should also.
Is the closure position an argument?
-------
∂10-Dec-84 1142 RPG Scheme conference report
∂10-Dec-84 0930 @MIT-MC:JINX@MIT-OZ Scheme conference report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 10 Dec 84 09:30:02 PST
Date: 10 Dec 1984 12:24 EST (Mon)
Message-ID: <JINX.12070348515.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Andy Freeman <ANDY@SU-SCORE.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: Scheme conference report
I would like to clarify (hopefully) a few points with respect
to the evaluation of combinations:
The operator position is a "distinguished" argument. In my
opinion it is the only position for which the evaluation order might
be relevant. If reflective procedures are present in an
implementation, then the operator position must be evaluated before
any operand expressions. Since in the common subset there is no
provision for reflective procedures, there is no need to specify any
particular order with respect to the operator.
In Will's last message there was a statement to the effect
that normal order evaluation was prohibited. I find this rather
surprising. One of Guy Steele's Rabbit compiler main points was that
normal order beta-subtitution could be used very successfully to
optimize Scheme code. In the absence of side-effects, and if the
programs terminate when using applicative order, there is no way to
determine whether normal or applicative order is used. A compiler can
use this profitably to postpone evaluation. A think that a more
appropriate statement is that portable programs should not depend on
the evaluation strategy used, ie. they should work in applicative
order, but different implementations may want to use different
strategies.
The order of argument evaluation was left unspecified for
various reasons:
- The order of argument evaluation is only relevant in the
presence of side-effects in some of the argument expressions. Scheme
is predominantly an applicative language (contrast with Pascal), and
good style requires that arguments to procedures (operands of
combinations) be side-effect free. By not specifying the order, it
was felt that code with such side-effects would be discouraged since
its effect would not be predictable.
- An optimizing compiler can do a better job if it has freedom
over the order in which it can execute expressions. Leaving the order
unspecified potentially allows a clever compiler to choose the optimal
order for each combination. Note that the meaning of a program can
only be changed by reordering if the argument expressions contain
side-effects. But this code could not be guaranteed to work in other
implementations with different default order for argument evaluation.
- Leaving the order of argument evaluation unspecified allows
a parallel implementation to evaluate in parallel. Note again that
the only programs whose semantics are not clear (and are therefore not
predictable) are those with side-effects in the operands of a
combination.
A marginally related issue is the issue of macros. In Scheme
there is not so much of a need to provide a macro facility as in other
dialects of Lisp. Macros are needed only to provide "nicer", more
readable syntax. In other dialects they are needed to extend the
langauge since there is no way of encapsulating an expression and an
environment. Freezing ("thunkifying", wrapping in a lambda
expression) an argument encapsulates a context and an expression in a
procedure which can then be invoked at will by the operator procedure.
While syntactically clumsy, it is conceptually very elegant. Note
that an optimizing compiler (Rabbit, for example) can eliminate most
or all of the overhead of freezing and thawing.
∂12-Dec-84 1711 RPG Re: Scheme conference report
∂12-Dec-84 1601 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: Scheme conference report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Dec 84 16:01:03 PST
Received: from unc by csnet-relay.csnet id aa04450; 12 Dec 84 15:04 EST
Received: by unc (4.12/4.7) id AA29958; Tue, 11 Dec 84 00:04:48 est
Date: Tue, 11 Dec 84 00:04:48 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8412110504.AA29958@unc>
To: ANDY@su-score.ARPA, scheme@mit-mc.ARPA
Subject: Re: Scheme conference report
Relative order of evaluation of the expressions in a combination is
not specified for at least two reasons:
1) It is poor coding style to depend on order of evaluation. If
there is an ordering constraint it should be made explicit
by using "let" or some such.
2) It is a severe constraint on the implementation for the language
to specify an evaluation order. What is easy for one machine
model or architecture may be difficult for another.
Note that Pascal and Scheme are not alone; neither C nor Common Lisp
specify the order of evaluation.
Kent Dybvig
∂12-Dec-84 1847 RPG
∂12-Dec-84 1837 KMP@MIT-MC
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Dec 84 18:37:11 PST
Date: 12 December 1984 21:37-EST
From: Kent M Pitman <KMP @ MIT-MC>
To: dyb%unc.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
Actually, Common Lisp does specify the order of evaluation as left to right.
It's tricky to find the passages in the CL manual which assure this, but
they are there if you look hard enough. The issue came up recently in the
Common Lisp discussion group and subsided after various obscure but recently
conclusive passages were cited.
Anyway, I agree it is reasonable to leave the order unspecified. It may be
computationally infeasible for the compiler to determine when order of
evaluation matters in many situations where "better code" would be available
if such a determination could be made.
∂15-Dec-84 2257 RPG Scheme bibliography
∂15-Dec-84 1655 @MIT-MC:CPH@MIT-OZ Scheme bibliography
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 15 Dec 84 16:55:16 PST
Date: Sat, 15 Dec 1984 19:53 EST
Message-ID: <CPH.12071740976.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: linus!ramsdell%UUCP@YALE.ARPA (John D. Ramsdell)
Cc: T-Discussion%MIT-OZ@MIT-MC.ARPA, Scheme@MIT-MC
Subject: Scheme bibliography
In-reply-to: Msg of 14 Dec 1984 13:44-EST
Fri 14 Dec 84 09:26:47 est from linus!ramsdell at Mitre-Bedford,
linus!ramsdell%UUCP at YALE.ARPA (John D. Ramsdell)
I believe that this is a complete list of the early Scheme papers:
Steele, Guy Lewis, Jr., and Gerald Jay Sussman. 1975. Scheme: An
interpreter for the extended lambda calculus. Memo 349, MIT
Artificial Intelligence Laboratory.
Steele, Guy Lewis, Jr., and Gerald Jay Sussman. 1976. Lambda: The
ultimate imperative. Memo 353, MIT Artificial Intelligence
Laboratory.
Steele, Guy Lewis, Jr. 1976. Lambda: The ultimate declarative. Memo
379, MIT Artificial Intelligence Laboratory.
Steele, Guy Lewis, Jr. 1977. Debunking the "expensive procedure
call" myth. In Proceedings of the National Conference of the ACM, pp.
153-62.
Steele, Guy Lewis, Jr., and Gerald Jay Sussman. January 1978. The
revised report on Scheme: A dialect of Lisp. Memo 452, MIT Artificial
Intelligence Laboratory.
Sussman, Gerald Jay, and Guy Lewis Steele, Jr. May 1978. The art of
the interpreter or, The modularity complex. Memo 452, MIT Artificial
Intelligence Laboratory.
Steele, Guy Lewis, Jr. May 1978. Rabbit: A compiler for Scheme.
Technical report 474, MIT Artificial Intelligence Laboratory.
∂16-Dec-84 2313 RPG continuation terminology
∂16-Dec-84 2039 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa continuation terminology
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 16 Dec 84 20:39:11 PST
Received: from indiana by csnet-relay.csnet id a001364; 16 Dec 84 23:35 EST
Received: by iuvax.UUCP (4.12/4.7)
id AA04292; Sun, 16 Dec 84 17:27:40 est
Date: Sun, 16 Dec 84 17:27:40 est
From: Chris Haynes <cth%indiana.csnet@csnet-relay.arpa>
To: scheme@mit-mc.ARPA
Subject: continuation terminology
We object strongly to the use of the term "escape procedure". The word
"escape" is far to limiting to describe continuations, which are good for so
much more. Also, the term "escape procedure" is strongly associated with the
limited facility by that name provided by most Lisp systems (which isn't good
for much besides "escaping"). If we adopt the old Lisp name, many will
assume that continuations aren't good for anything more than Lisp escape
procedures, and will miss what we feel is one of the most important
distinguishing features of Scheme.
We find the term "continuation" to be quit satisfactory in most contexts, and
it agrees with the name "call-with-current-continuation". However, we
recognize that in the context of denotational semantics or implementation
discussions, there is possibility of confusing continuations as first-class
programming objects and their semantic or implementation counterparts. Thus
additional terminology is desirable when such distinctions must be made, and
to standardize such terminology it should probably be used in the Revised
Revised Report. We suggest the term "continuation object" for this purpose,
though it is not wonderful and we welcome other suggestions.
-- Chris Haynes
Dan Friedman
Eugene Kohlbecker
∂17-Dec-84 1524 RPG continuation terminology
∂17-Dec-84 1523 JAR@MIT-MC continuation terminology
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Dec 84 15:23:41 PST
Date: 17 December 1984 18:23-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: continuation terminology
To: cth%indiana.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
In-reply-to: Msg of Sun 16 Dec 84 17:27:40 est from Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
Date: Sun, 16 Dec 84 17:27:40 est
From: Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
We object strongly to the use of the term "escape procedure"...
My only objection to the terms "continuation" and "continuation object"
is that the presence of fluids and/or UNWIND-PROTECT mean that the thing
created by the user-visible CATCH or CONTINUE or CALL-... or whatever is
more than just a continuation, since it implicitly includes a reference
to the dynamic state. There is a low-level thing which really does give
you a continuation, but I expect that the mechanism which does the right
thing with fluids would be the normal one used by users.
I don't have any new alternative term to propose, however.
Of course, we decided not to decide whether or not the essential
scheme's continuation procuration combinator dealt properly with fluids,
since essential scheme doesn't deal with fluids at all. It seems to me
that any fluid mechanism whatsoever must distinguish between
continuations and continuation+state things. As things are, my guess is
that it would be up to the implementor which of these two things the
essential dialect's CALL-... gives you. (This might be the wrong thing,
but I won't argue that position here - this message is already too long.)
(By the way, no Lisp has never had escape procedures per se; the usual
CATCH/THROW mechanism doesn't introduce a new kind of object. I'm not
convinced that the term "escape procedure" is as broken as you think it
is, or that it necessarily has such strong connotations. But I'm not
partial to the term.)
∂18-Dec-84 2009 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Common Lisp order of evaluation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Dec 84 20:09:07 PST
Received: from unc by csnet-relay.csnet id ac00691; 18 Dec 84 14:57 EST
Received: by unc (4.12/4.7) id AA12698; Fri, 14 Dec 84 10:29:23 est
Date: Fri, 14 Dec 84 10:29:23 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8412141529.AA12698@unc>
To: KMP@mit-mc.ARPA, SCHEME@mit-mc.ARPA
Subject: Common Lisp order of evaluation
If you have found passages which indicate a specific order of
evaluation, I'd like to know about it. All that I have found
in scouring the manual several times over, in several different
versions over the years, is that arguments are 'processed' in
left-right order *once they reach the caller*. Regardless of
any intentions on the designer's part, or any decisions of
discussion groups, any feature of the language that is not
spelled out is subject to interpretation. There is certainly
nowhere in the manual that states that arguments are evaluated
in left-right order.
∂19-Dec-84 0850 @MIT-MC:rhh@MIT-VAX Re: Common Lisp order of evaluation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Dec 84 08:49:55 PST
Received: by mit-vax.Mit-chaos.Arpa (4.12/4.8) id AA25785; Wed, 19 Dec 84 11:40:26 est
Date: Wed, 19 Dec 84 11:40:26 est
From: Bert Halstead <rhh@mit-vax>
To: KMP@mit-mc.ARPA, SCHEME@mit-mc.ARPA, dyb%unc.csnet@csnet-relay.arpa
Subject: Re: Common Lisp order of evaluation
The following passages out of the Common Lisp book may be relevant:
"setf carefully arranges to preserve the usual left-to-right order
in which the various subforms are evaluated." (p. 97)
"Macros that manipulate generalized variables must guarantee the
'obvious' semantics: subforms of generalized-variable references
are evaluated exactly as many times as they appear in the source
program, and they are evaluated in the same order as they appear
in the source program." (p. 99)
-Bert
∂19-Dec-84 0912 @MIT-MC:CPH@MIT-OZ Common Lisp order of evaluation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Dec 84 09:12:05 PST
Date: Wed, 19 Dec 1984 12:12 EST
Message-ID: <CPH.12072705547.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Scheme@MIT-MC
Subject: Common Lisp order of evaluation
In-reply-to: Msg of 19 Dec 1984 11:40-EST from Bert Halstead <rhh at mit-vax>
Come on, folks... This really isn't a great place to argue about what
order Common Lisp evaluates its arguments. I for one don't care and
would rather not know.
∂23-Dec-84 0901 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa length vs. list-length
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Dec 84 09:00:57 PST
Received: from unc by csnet-relay.csnet id ag24249; 23 Dec 84 11:49 EST
Received: by unc (4.12/4.7) id AA29885; Sun, 23 Dec 84 01:06:25 est
Date: Sun, 23 Dec 84 01:06:25 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8412230606.AA29885@unc>
To: scheme@mit-mc.ARPA
Subject: length vs. list-length
My primary concern about the length function seems to have been
lost in the ensuing discussions. I do not insist that Scheme
have a generic length function. I do insist that the naming
convention for such functions be consistent.
Doesn't this look a little odd?
(define generic-length
(lambda (x)
(cond ((string? x) (string-length x))
((vector? x) (vector-length x))
((list? x) (length x)))))
I like this much better:
(define generic-length
(lambda (x)
(cond ((string? x) (string-length x))
((vector? x) (vector-length x))
((list? x) (list-length x)))))
We have list-ref, vector-ref and string-ref. Why should we not
have list-length rather than length? While we're at it, why
not have list-append rather than append? Any functions that makes
sense for strings, lists, and vectors should be named with
the appropriate type-name prefix. (Even though the language
doesn't specify a reverse function for vectors or strings
and since such functions would be reasonable, the reverse
function for lists should be named list-reverse.)
∂23-Dec-84 2330 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa list-length
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Dec 84 23:30:17 PST
Received: from brandeis by csnet-relay.csnet id a026028; 24 Dec 84 2:15 EST
Received: by brandeis.ARPA (4.12/)
id AA06312; Sun, 23 Dec 84 22:31:44 est
Date: 23 Dec 1984 22:30-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: list-length
To: scheme@mit-mc.ARPA
Cc: dyb%unc.csnet@csnet-relay.arpa
Message-Id: <472707016/mw@brandeis>
I vote for list-length over length, too. I think we just went over
that one a little too rapidly at the meeting.
-- Mitch Wand
∂24-Dec-84 1350 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa list-length
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Dec 84 13:50:48 PST
Received: from brandeis by csnet-relay.csnet id a026028; 24 Dec 84 2:15 EST
Received: by brandeis.ARPA (4.12/)
id AA06312; Sun, 23 Dec 84 22:31:44 est
Date: 23 Dec 1984 22:30-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: list-length
To: scheme@mit-mc.ARPA
Cc: dyb%unc.csnet@csnet-relay.arpa
Message-Id: <472707016/mw@brandeis>
I vote for list-length over length, too. I think we just went over
that one a little too rapidly at the meeting.
-- Mitch Wand
∂28-Dec-84 1428 JAR@MIT-MC list-length
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Dec 84 14:28:26 PST
Date: 28 December 1984 17:29-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: list-length
To: SCHEME @ MIT-MC
In-reply-to: Msg of 23 Dec 1984 22:30-EST from mw%brandeis.csnet at csnet-relay.arpa
LIST-APPEND, LIST-REVERSE, LIST-SORT, LIST-MAPCAR, ...